<?php

namespace App\Service;

use App\Common\Common;
use App\Repositories\ClockConfigRepository;
use App\Repositories\ClockRecordRepository;
use App\Repositories\CourseRepository;

use App\Repositories\EmployeesRepository;
use App\Transformers\Course\ShowTransformer;
use function Symfony\Component\VarDumper\Dumper\esc;

class EmployeesService extends BaseService {
    protected $courseRepository;
    protected $employeesRepository;
    protected $clockConfigRepository;
    protected $schoolService;
    protected $clockRecordRepository;

    public function __construct(
        CourseRepository $courseRepository,
        EmployeesRepository $employeesRepository,
        ClockConfigRepository $clockConfigRepository,
        SchoolService $schoolService,
        ClockRecordRepository $clockRecordRepository
    ) {
        $this->courseRepository = $courseRepository;
        $this->employeesRepository = $employeesRepository;
        $this->clockConfigRepository = $clockConfigRepository;
        $this->schoolService = $schoolService;
        $this->clockRecordRepository = $clockRecordRepository;
    }

    /**
     * 员工列表
     * @param array $params
     */
    public function list(array $params) {
        if (isset($params['school_id'])) {
            $params['with_has_where'] = ['employeesSchool' => ['school_id' => $params['school_id']]];
        }
        if (isset($params['identity_id'])) {
            $params['where'] = ['identity_id' => Common::USER_IDENTITY['teacher']];
        }
        $employeesObject = $this->employeesRepository->list($params);
        return !empty($employeesObject) ? $employeesObject->toArray() : [];
    }

    /**
     * 用户登录
     * @param array $params
     * @return mixed
     * @throws \Exception
     */
    public function login(array $params) {
        $employeesInfo = $this->employeesRepository->showByWhere(['account' => $params['account']], ['employeesSchool']);
        if (empty($employeesInfo)) {
            throw new \Exception(CommonService::getExceptionInfo(1008), 1008);
        }
        $employeesInfo = $employeesInfo->toArray();
        $employeesInfo['school_id'] = $employeesInfo['employees_school'][0]['id'];
        if (md5(md5($params['password'])) != $employeesInfo['password']) {
            throw new \Exception(CommonService::getExceptionInfo(1009), 1009);
        }
        unset($employeesInfo['password']);
        session(['employeesInfo' => $employeesInfo]);
        return $employeesInfo;
    }

    /**
     * 打卡
     * @param array $params
     * @return mixed
     */
    public function clock(array $params) {
        $clockRecordInfo = [];
        $data['clock_result'] = 0;
        $userInfo = session('employeesInfo');
        $schoolInfo = $this->schoolService->list();
        $clockConfigInfo = $this->clockConfigRepository->showByWhere(['identity_id' => $userInfo['identity_id'], 'weeks' => date('w')]);
        if (empty($clockConfigInfo)) {
            throw new \Exception(CommonService::getExceptionInfo(1010), 1010);
        }
        $clockConfigInfo = $clockConfigInfo->toArray();
        $switch = true;
        foreach ($schoolInfo as $config) {
            $distance = CommonService::getDistance($params['lon'], $params['lat'], $config['lon'], $config['lat']);
            if ($distance <= CommonService::CLOCK_DISTANCE_ERROR) {
                $switch = false;
                $data['clock_distance'] = $distance;
                //获取今天打卡信息
                $oldClockRecordInfo = $this->clockRecordRepository->showByWhere(['employees_id' => $userInfo['id'], 'begin_time' => ['condition' => '>', 'value' => date('Y-m-d')]]);
                //上班打卡
                if ($params['clock_type'] == 1) {
                    $data = $this->clockBeginWork($oldClockRecordInfo, $params, $data, $clockConfigInfo, $config, $distance);
                } else {
                    $data = $this->clockEndWork($oldClockRecordInfo, $params, $data, $clockConfigInfo, $config, $distance);
                }
                break;
            }
        }
        if ($switch){
            $data = ['clock_result'] = 2;
            $data = ['abnormal_status'] = 2;
        }
        return $data;
    }


    private function clockRecordSave() {
        $clockConfigArr = $this->getClockConfigInfo();
    }

    /**
     * 获取打开配置信息
     * @return mixed
     */
    private function getClockConfigInfo() {
        return $this->clockConfigRepository->list()->toArray();
    }

    /**
     * 上班打卡
     * @param $oldClockRecordInfo
     * @param $params
     * @param $returnData
     * @param $clockConfigInfo
     * @return mixed
     */
    private function clockBeginWork($oldClockRecordInfo, $params, $returnData, $clockConfigInfo, $schoolInfo, $distance) {
        if (!empty($oldClockRecordInfo)) { //已有打卡记录
            $oldClockRecordInfo = $oldClockRecordInfo->toArray();
            //如果之前打卡正常则直接返回
            if ($oldClockRecordInfo['clock_result'] == 1) {
                $returnData['clock_result'] = 1;
                return $returnData;
            }
            //如果偏移可以重新打卡
            if ($oldClockRecordInfo['abnormal_status'] == Common::CLOCK_STATUS['location_offset']) {
                if ($clockConfigInfo['begin_work_time'] >= date('Y-m-d H:i:s')) {
                    $updateData = [
                        'clock_result'        => 1,
                        'begin_abnormal_info' => '偏移后重新打卡',
                    ];
                    $returnData['clock_result'] = 1;
                } else { //迟到
                    $updateData = [
                        'clock_result'        => 2,
                        'abnormal_status'     => Common::CLOCK_STATUS['late'],
                        'begin_abnormal_info' => '偏移后重新打卡',
                    ];
                    $returnData['clock_result'] = 2;
                    $returnData['abnormal_status'] = Common::CLOCK_STATUS['late'];
                }
            } else {
                $returnData['clock_result'] = $oldClockRecordInfo['clock_result'];
                $returnData['abnormal_status'] = $oldClockRecordInfo['abnormal_status'];
                return $returnData;
            }
        } else { //没有打卡记录
            if ($clockConfigInfo['begin_work_time'] >= date('Y-m-d H:i:s')) {
                $updateData = [
                    'clock_result'        => 1,
                    'begin_abnormal_info' => '首次打卡',
                ];
                $returnData['clock_result'] = 1;
            } else { //迟到
                $updateData = [
                    'clock_result'        => 2,
                    'abnormal_status'     => Common::CLOCK_STATUS['late'],
                    'begin_abnormal_info' => '首次打卡',
                ];
                $returnData['clock_result'] = 2;
                $returnData['abnormal_status'] = Common::CLOCK_STATUS['late'];
            }
        }
        $updateData = array_merge($updateData, [
            'begin_address'     => $params['location_message'],
            'begin_time'        => date('Y-m-d H:i:s'),
            'begin_work_remark' => 'schoolId : ' . $schoolInfo['id'] . ' distance:' . $distance
        ]);
        $updateData['last_begin_work_record'] = json_encode(['old' => $oldClockRecordInfo['last_begin_work_record'], 'new' => $updateData]);
        $this->clockRecordRepository->update($oldClockRecordInfo['id'], $updateData);
        return $returnData;
    }

    /**
     * 下班打卡
     * @param $oldClockRecordInfo
     * @param $params
     * @param $returnData
     * @param $clockConfigInfo
     * @param $schoolInfo
     * @param $distance
     * @return mixed
     * @throws \Exception
     */
    private function clockEndWork($oldClockRecordInfo, $params, $returnData, $clockConfigInfo, $schoolInfo, $distance) {
        if (empty($oldClockRecordInfo)) {
            throw new \Exception(CommonService::getExceptionInfo(1011), 1011);
        }
        if ($clockConfigInfo['end_work_time'] <= date('Y-m-d H:i:s')) {
            $updateData = [
                'clock_result' => 1,
            ];
            $returnData['clock_result'] = 1;
        } else { //早退
            $updateData = [
                'clock_result'    => 2,
                'abnormal_status' => Common::CLOCK_STATUS['leave_early'],
            ];
            $returnData['clock_result'] = 2;
            $returnData['abnormal_status'] = Common::CLOCK_STATUS['leave_early'];
        }
        $updateData = array_merge($updateData, [
            'end_address'     => $params['location_message'],
            'end_time'        => date('Y-m-d H:i:s'),
            'end_work_remark' => 'schoolId : ' . $schoolInfo['id'] . ' distance:' . $distance,
        ]);
        $updateData['last_end_work_record'] = json_encode(['old' => $oldClockRecordInfo['last_end_work_record'], 'new' => $updateData]);
        $this->clockRecordRepository->update($oldClockRecordInfo['id'], $updateData);
        return $returnData;
    }


}
